<?php
class UsersController extends AppController {

	var $name = 'Users';
	var $components = array('Email', 'Cookie');
	
	function beforeFilter() {
		parent::beforeFilter();	
		//auth komponensben használt mezõnevek
		$this->Auth->fields = array(
			'username' => 'email',
			'password' => 'pass'
			);
		$this->Auth->userScope = array('User.active >' => 0);	//deleted and not activated users denied
		$this->Auth->allow('register', 'activate_account', 'apiindex');
		$this->Auth->autoRedirect = false;
		
		if($this->data){
			App::import('Sanitize');
			$this->data['User']['email'] = Sanitize::paranoid($this->data['User']['email'], array('@', '-', '_', '.'));
			$this->data['User']['pass'] = isset($this->data['User']['pass']) ? Sanitize::html($this->data['User']['pass']) : null;
		}
	}
	
	function isAuthorized(){
// if(isset($this->params['admin'])) {  //admin utak kiszûrése
		if($this->Auth->user('group_id') == $this->Session->read('Settings.adminPermission')){		//admin jogosultságú júzerek
			return true;
		}
else if($this->action == 'apiindex') return true;
		else{		//free user / premium user / business user
			if(in_array($this->action, array(
														'edit',
														'delete',
														'logout'		//fura de ez is kell neki - jobban mondva nem fura :)
														))){
				return true;
			}
		}
		return false;		//minden más tiltva
	}

function apiindex(){
		//$this->User->unBindModel(array('hasMany' => array('Message')));
		$this->User->recursive = 0;
		$this->set('users', $this->paginate());
	}


	function login(){
		//real login functionality is behind the auth component scenes, here we have just the extras
		if($this->Auth->user('id')){
			$this->User->id = $this->Auth->user('id');
			$this->User->saveField('last_login', date("Y-m-d H:i:s"));
			if(!empty($this->data) && $this->data['User']['remember_me']){
				$cookie = $this->Auth->user('id');
				$this->Cookie->write('Auth.User', $cookie, true, '+2 weeks');
				unset($this->data['User']['remember_me']);
			}
			$this->redirect($this->Auth->redirect());
		}
		if(empty($this->data)){
			$cookie = $this->Cookie->read('Auth.User');
			if(!is_null($cookie)) {
				if($this->Auth->login($cookie)){
					//  Clear auth message, just in case we use it.
					$this->Session->del('Message.auth');
					$this->redirect($this->Auth->redirect());
				}
				else{ // Delete invalid Cookie
					$this->Cookie->del('Auth.User');
				}
			}
		}
	}
	
	function logout(){
		$this->Cookie->del('Auth.User');
		$this->redirect($this->Auth->logout());
	}
	
/**
 * Allows guests to register via web form and send them a verification email
*/
	function register() {
		if($this->Auth->user('id'))
			$this->redirect('/');	//if a user already signed in nothing here is for her
		//first chechk if anyone can register
		if($this->User->find('count') >= $this->Option->field('value', array('name' => 'max_users'))){
			$this->redirect(array('controller' => 'pages', 'action' => 'display', 'registrationIsClosed'));
		}
		if(!empty($this->data)){
			if($this->data['User']['pass'] && $this->data['User']['pass_confirm'] && $this->data['User']['pass'] == $this->Auth->password($this->data['User']['pass_confirm'])) {
				$this->data['User']['created'] = date('Y-m-d H:i:s');
				$this->data['User']['active'] = 0;
				$this->data['User']['group_id'] = 2;
				$this->User->create();
				if($this->User->save($this->data)){
					$link = $this->_createRegLink($this->data['User']['email'], $this->data['User']['pass']);
					if(!$this->Option->field('value', array('name' => 'user_reg_auto'))){	//if user_reg_auto is 0 send a mail, if 1 activate the account
						//send an email to verify registering the link is an md5 of email + first 10 chars from the sha1-ed pass filed
						$this->Email->to = $this->data['User']['email'];
						$this->Email->subject = __('Welcome at SociALL', true);
						$this->Email->from = __('SociALL', true) . ' ' . '<register@sociall.cc>';
						$this->Email->template = 'register_beta_mail';	//app/views/elemets/email/text/register_mail.ctp
						$this->Email->sendAs = 'text'; // because we like to send simple mail
						$this->set('link', $link);
						if($this->Email->send()){
							$this->redirect(array('action' => 'activate_account'));
						}
						else{
							$this->User->del($this->User->getLastInsertID());
							$this->log(__('Activation mail did not sent because of some error.', LOG_DEBUG));
							die(__('Activation mail did not sent because of some error.'));
						}
					}
					else{	//user_reg_auto is 1, so active without email confirmation
						$this->redirect(array('action' => 'activate_account/' . $link));
					}
				}
			}
			else
				$this->Session->setFlash(__('Passwords are not the same. Please try again', true));
		}
	}

/**
 * Allow users to activate their account
 * Users get here when they filled the registration form
 */
	function activate_account($link = null){
		if($link){	//the url called with a link parameter, so we have to validate
			$userid = $this->User->find('first', array('fields' => 'id', 'conditions' => 'MD5(CONCAT(email, LEFT(pass, 10))) = "' . $link . '"', 'recursive' => -1));
			if($userid = $userid['User']['id']){	//the user is found set him active
				$this->set('activated', $this->User->activate_user($userid));
			}
		}
		else{	//the url called without any parameters so we just let the user know he will get a mail soon
			$this->set('mail', true);
		}
	}

/**
 * Creates user registration link
 *
 * @param string $email The email address
 * @param string $pass The sha1-ed password
 * @access private
 */
	function _createRegLink($email, $pass){
		$this->set('link', md5($email.substr($pass, 0, 10)));
		return(md5($email.substr($pass, 0, 10)));
	}


/*
 * Users could edit their own user data: email and pass
 * @access public
 * @permission user level
 */
	function edit(){
		$this->User->id = $this->Auth->user('id');
		$this->_edit();
	}

/*
 * Users could set themselves as deleted, they will redirected to the logout page
 * @access public
 * @permission user level
 */
	function delete() {
		if($this->User->setDeleted($this->Auth->user('id'))) {
			$this->Session->setFlash(__('User deleted', true));
			//$this->redirect(array('action'=>'logout'));
		}
	}

/*
 * List of users
 * @access public
 * @permission admin level
 */
	function admin_index() {
		$this->User->recursive = 1;
		$this->set('users', $this->paginate());
	}	

/*
 * Admins could create new users directly without the reistration process
 * @access public
 * @permission admin level
 */
	function admin_add() {
		if (!empty($this->data)) {
			$this->User->create();
			if ($this->User->save($this->data)) {
				$this->Session->setFlash(__('The User has been saved', true));
				$this->redirect(array('action'=>'index'));
			} else {
				$this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
			}
		}
	}

/*
 * Admins could edit all of the users data inculding email,  pass, type, paid, etc
 * @access public
 * @permission admin level
 */
	function admin_edit($id = null) {
		$this->User->id = $id ? $id : $this->data['User']['id'];
		$this->_edit();
	}
/*
 * Admins could set any users as deleted
 * @access public
 * @permission admin level
 */
	function admin_delete($id = null) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid id for User', true));
			$this->redirect(array('action'=>'index'));
		}
		if ($this->User->setDeleted($id)) {
			$this->Session->setFlash(__('User deleted', true));
			$this->redirect(array('action'=>'index'));
		}
	}

/*
* Helper for user edit as admin_edit and edit are quite similar
* @access private
* @permission user and admin level
*/
	function _edit(){
		$this->User->unBindModel(array('hasMany' => array('Message')));
		$this->User->Group->unBindModel(array('hasMany' => array('User')));
		$this->User->Account->unBindModel(array('belongsTo' => array('User')));
		$user = $this->User->find('first', array(
															'conditions' => array('User.id' => $this->User->id),
															'recursive' => 2
															));
		$this->set('consumer_key', $this->Option->field('value', array('name' => 'twitter_consumer_key')));
		$this->set('consumer_secret', $this->Option->field('value', array('name' => 'twitter_secret_key')));

		$fbook = $this->User->Account->find('first',
											  array(
												'conditions' => array(
																		'user_id' => $this->User->id,
																		'community_id' => 3	//hardcoded
																		)
												));
						
		$facebookData = $errorz4v = null;
		foreach($user['Account'] as $index => $account){
			//get & check user info on the social network sites
			if($account['community_id'] == 1){	//todo: HC iwiw
				App::import('Vendor', 'iwiw');
				$iwiwSid = $this->Session->read('iwiwSid.acc_'.$account['id']);
				$iwiw = new Iwiw($iwiwSid);
				$account['pass'] = $this->_decodePass($account['pass']);
				//debug($account);
				$iwiwSid = $iwiw->login($account);
				//debug($iwiwSid);
				if(isset($iwiwSid['error'])){
					$errorz4v[$account['id']] = __('Iwiw connection error', true) . ' ' . __('Bad name or password', true);
					$e = array(
								'type' => 'iwiwError',
								'data' => array(
												'account' => $account['id'],
												'error' => $iwiwSid['error']
											)
								);
					$this->log('verify_credentials: ' . print_r($e, true), LOG_DEBUG);
				}
			}
			if($account['community_id'] == 2){	//todo: HC twitter
				App::import('Vendor', 'twitterOAuth', array('file' => 'twitterOAuth.php'));
				$secrets = unserialize($account['extras']);
				$secrets = array(
							'oauth_token' => $this->_decodePass($secrets['oauth_token']),
							'oauth_token_secret' => $this->_decodePass($secrets['oauth_token_secret'])
							);

				$twitterOAuth = new TwitterOAuth(
										$this->Option->field('value', array('name' => 'twitter_consumer_key')),
										$this->Option->field('value', array('name' => 'twitter_secret_key')),
										$secrets['oauth_token'],
										$secrets['oauth_token_secret']);
//			   $usr = json_decode($twitterOAuth->OAuthReques('https://twitter.com/account/verify_credentials.json',array(),'GET'));
$usr = $twitterOAuth->get('account/verify_credentials');
				if(isset($usr->error)){
					$errorz4v[$account['id']] = __('Twitter verify credentials failed', true) . ': ' . $usr->error;
					$e = array(
								'type' => 'twitterError',
								'data' => array(
												'account' => $account['id'],
												'error' => $usr->error . ' :: ' . $usr->request
											)
								);
					$this->log('verify_credentials: ' . print_r($e, true), LOG_DEBUG);
				}
			}
			elseif($account['community_id'] == 3){	//todo: HC facebook
				//checks if facebook session is still alive
				App::import('Vendor', 'facebook');
				$app_id = $this->Option->field('value', array('name' => 'facebook_app_id'));
				$api_key = $this->Option->field('value', array('name' => 'facebook_api_key'));
				$secret = $this->Option->field('value', array('name' => 'facebook_secret_key'));
				$facebook = new Facebook($api_key, $secret);
				$facebookUser = unserialize($account['extras']);
				$facebook->set_user($facebookUser['userId'], $account['pass']);
				
				$facebookAuthorizeLink = $this->requestAction('/accounts/facebookGetAuthorizeLink/'.$api_key);
				$facebookData[$account['id']]['authorizeLink'] = $facebookAuthorizeLink;

				if(strpos($account['pass'], '__.86400.')){
					$errorz4v[$account['id']] = __('Your Facebook connection is temporary or no longer exists. You should renew the connection between Facebook and SociALL', true);
				}

				try{
					$this->set('facebookLiveSession', $facebook->get_loggedin_user());
					$perm['read_stream'] = $facebook->api_client->users_hasAppPermission('read_stream');
					$perm['publish_stream'] = $facebook->api_client->users_hasAppPermission('publish_stream');
					$perm['offline_access'] = $facebook->api_client->users_hasAppPermission('offline_access');
					$facebookData[$account['id']]['permissions'] = $perm;
					if(($perm['read_stream'] + $perm['publish_stream'] + $perm['offline_access']) != 3){
						$errorz4v[$account['id']] = __('You did not provided all the 3 neccessary rights for SociALL. You should give all the 3 permissions again.', true);
						$e = array(
									'type' => 'facebookPermissionError',
									'data' => array(
														'account' => $account['id'],
														'error' => array(
																			'$perm[read_stream] = ' . $perm['read_stream'],
																			'$perm[publish_stream] = ' . $perm['publish_stream'],
																			'$perm[offline_access] = ' . $perm['offline_access']
																			)
														)
									  );
						$this->log('Facebook permissions: ' . print_r($e, true), LOG_DEBUG);
					}
				}
				catch(Exception $e){
					$facebookData[$account['id']]['permissions'] = $e->getMessage();
				}
			}
		}

		if(!empty($this->data)){	//the user submitted some data
			if(!$this->data['User']['pass_change'] && !$this->data['User']['pass_confirm']){
				//the password is not be changed
				$this->data['User']['pass'] = $user['User']['pass'];
			}
			else{
				if($this->data['User']['pass_change'] != $this->data['User']['pass_confirm']){
					$this->Session->setFlash(__('Passwords are not the same. Please try again', true));
				}
				elseif($this->data['User']['pass_change'])
					$this->data['User']['pass'] = $this->Auth->password($this->data['User']['pass_change']);
			}
			
			//User.active == 2 means experimental mode is on, 1 means off, 0 means the user is not verified
			$active = $this->data['User']['active'] ? 2 : 1;
			if($active != $user['User']['active'])
				$this->data['User']['active'] = $active;
			
			if($this->User->save($this->data)){
				$this->Session->setFlash(__('The User has been saved', true));
			}
			else{
				$this->Session->setFlash(__('The User could not be saved. Please, try again.', true));
			}
		}
		

		if($this->Auth->user('group_id') == $this->Session->read('Settings.adminPermission')){
			$this->set('userCount', $this->User->find('count'));
		}

		$this->User->unBindModel(array('hasMany' => array('Message')));
		$this->User->Group->unBindModel(array('hasMany' => array('User')));
		$this->User->Account->unBindModel(array('belongsTo' => array('User')));
		$user = $this->User->find('first', array(
															'conditions' => array('User.id' => $this->User->id),
															'recursive' => 2
															));
		//debug($errorz4v);
		$this->set('facebookData', $facebookData);
		$this->set('user', $user);
		$this->set('errorz4v', $errorz4v);
	}
	
}
?>
